package com.jt1078.streamserver.controller;

import com.jt1078.streamserver.manager.JT1078SessionManager;
import com.jt1078.streamserver.flv.FLVMuxer;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.io.OutputStream;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
public class HttpStreamController {
    @GetMapping("/stream/{sim}/{channel}.flv")
    public void streamFlv(@PathVariable String sim, @PathVariable int channel, HttpServletResponse response) throws Exception {
        response.setContentType("video/x-flv");
        OutputStream out = response.getOutputStream();
        JT1078SessionManager.printSessions();

        // 1. 注册订阅队列
        BlockingQueue<byte[]> queue = new LinkedBlockingQueue<>(200);
        JT1078SessionManager.JT1078Session session = JT1078SessionManager.getSession(sim);
        if (session == null) return;
        List<BlockingQueue<byte[]>> subList = session.subscribers.computeIfAbsent(channel, k -> new CopyOnWriteArrayList<>());
        subList.add(queue);

        try {
            // 2. 写FLV头
            out.write(FLVMuxer.generateFLVHeader());
            out.flush();
            boolean avcSent = false;
            byte[] sps = session.spsMap.get(channel), pps = session.ppsMap.get(channel);
            int ts = 0;
            while (true) {
                byte[] nalu = queue.poll(2, TimeUnit.SECONDS);
                if (nalu == null) continue;

                // === 自动判断起始码长度，正确提取 NALU type ===
                int offset = (nalu.length > 4 && nalu[2] == 1) ? 3 : 4;
                int naluType = nalu.length > offset ? (nalu[offset] & 0x1F) : -1;

                if (!avcSent && sps != null && pps != null && naluType == 5) {
                    out.write(FLVMuxer.createAvcSeqHeader(sps, pps));
                    out.flush();
                    avcSent = true;
                }
                if (avcSent) {
                    boolean key = (naluType == 5);
                    out.write(FLVMuxer.createVideoTag(nalu, key, ts));
                    out.flush();
                    ts += 40;
                }
            }
        } finally {
            // 3. 拉流断开时移除订阅队列
            subList.remove(queue);
        }
    }


    @GetMapping("/audio/{sim}/{channel}.g711a")
    public void streamAudio(@PathVariable String sim, @PathVariable int channel, HttpServletResponse response) throws Exception {
        response.setContentType("audio/basic"); // 或其它 mime
        OutputStream out = response.getOutputStream();

        BlockingQueue<byte[]> queue = new LinkedBlockingQueue<>(200);
        JT1078SessionManager.JT1078Session session = JT1078SessionManager.getSession(sim);
        if (session == null) return;
        List<BlockingQueue<byte[]>> subList = session.audioSubscribers.computeIfAbsent(channel, k -> new CopyOnWriteArrayList<>());
        subList.add(queue);

        try {
            while (true) {
                byte[] audio = queue.poll(2, TimeUnit.SECONDS);
                if (audio == null) continue;
                out.write(audio);
                out.flush();
            }
        } finally {
            subList.remove(queue);
        }
    }

}
